﻿// //  ********************************************************************************
// //  Copyright (C) 2016 Sebastian Kenter. All rights reserved.
// // 
// //  Name    : PhotonServerProject | LoginServer | AccountDeleteRequestHandler.cs
// //  Created : 2016 - 04 - 08 15:01
// //  Modified: 2016 - 04 - 18 09:38
// //  ********************************************************************************

using System;
using ExitGames.Logging;
using NHibernate;
using PhotonServerCommon;
using PhotonServerCommon.Entities.Domain;
using PhotonServerCommon.Enums;
using PhotonServerCommon.Messages;
using PhotonServerCommon.Messages.Helper;
using PhotonServerFramework.Implementation.Database;
using PhotonServerFramework.Implementation.Handler;
using PhotonServerFramework.Implementation.Server;
using PhotonServerFramework.Implementation.Telegram;
using PhotonServerFramework.Interfaces.Server;
using PhotonServerFramework.Interfaces.Telegram;

namespace LoginServer.Handler.Request
{
    public class AccountDeleteRequestHandler : ServerTelegramHandler
    {
        public override ILogger Logger { get; }
        public override Guid HandlerId { get; set; } = Guid.NewGuid();
        public override HandlerTypes HandlerType => HandlerTypes.Request;
        public override byte HandlerCode => (byte) OperationCodes.Account;
        public override int HandlerSubCode => (int) OperationSubCodes.DeleteAccount;

        public AccountDeleteRequestHandler(ILogger logger)
        {
            Logger = logger;
        }

        public override bool HandleTelegram(ITelegram telegram, IServerPeer serverPeer)
        {
            bool handled = false;

            Logger.InfoFormat("Trying to handle telegram of type={0} with code={1}, subcode={2}", telegram.Type,
                (OperationCodes) telegram.TelegramCode, (OperationSubCodes) telegram.TelegramSubCode);

            ServerPeer peer = serverPeer as ServerPeer;
            AccountT account = null;

            AccountDeleteMessage message =
                MessageSerializer.DeserializeMessage<AccountDeleteMessage>(
                    (byte[]) telegram.TelegramParameters[(byte) ParameterCodes.AccountDeleteMessage]);

            if (message != null)
            {
                if (peer != null)
                {
                    using (ISession session = SessionManager.OpenSession())
                    {
                        using (ITransaction transaction = session.BeginTransaction())
                        {
                            try
                            {
                                account =
                                    session.QueryOver<AccountT>()
                                        .Where(c => c.AccountName == message.LoginName)
                                        .SingleOrDefault();
                                transaction.Commit();
                            }
                            catch (Exception ex)
                            {
                                Logger.ErrorFormat("Operation failed with: {0}", ex.Message);
                                transaction.Rollback();
                            }
                        }

                        if (account != null)
                        {
                            Logger.InfoFormat("Found account for account name {0}", account.AccountName);

                            using (ITransaction transaction = session.BeginTransaction())
                            {
                                try
                                {
                                    session.Delete(account);
                                    transaction.Commit();
                                }
                                catch (Exception ex)
                                {
                                    Logger.ErrorFormat("Operation failed with: {0}", ex.Message);
                                    transaction.Rollback();
                                }
                            }

                            peer.SendTelegram(new
                                ResponseTelegram
                                              {
                                                  TelegramCode = telegram.TelegramCode,
                                                  TelegramSubCode = telegram.TelegramSubCode,
                                                  TelegramParameters = telegram.TelegramParameters,
                                                  ReturnCode = (short) ErrorCodes.AccountDeleted,
                                                  DebugMessage =
                                                      EnumHelper.GetEnumDescription(
                                                          ErrorCodes.AccountDeleted)
                                              });
                            handled = true;
                        }
                        else
                        {
                            Logger.InfoFormat("Account for account name {0} not found",
                                telegram.TelegramParameters[(byte) ParameterCodes.LoginName].ToString());

                            peer.SendTelegram(new
                                ResponseTelegram
                                              {
                                                  TelegramCode = telegram.TelegramCode,
                                                  TelegramSubCode = telegram.TelegramSubCode,
                                                  TelegramParameters = telegram.TelegramParameters,
                                                  ReturnCode = (short) ErrorCodes.AccountNotFound,
                                                  DebugMessage =
                                                      EnumHelper.GetEnumDescription(
                                                          ErrorCodes.AccountNotFound)
                                              });
                            handled = true;
                        }

                        session.Close();
                    }
                }
                else
                {
                    Logger.ErrorFormat("Server peer invalid - cannot process telegram!");
                }
            }
            else
            {
                Logger.ErrorFormat("Message invalid - cannot process telegram!");
            }

            return handled;
        }
    }
}
